/**
 * 
 */
package de.oszimtcc.timetablecore;

import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import android.content.ContentValues;
import android.os.Handler;
import android.os.Message;
import de.oszimtcc.framework.Logger;
import de.oszimtcc.timetable.R;
import de.oszimtcc.timetable.TimetableApplication;
import de.oszimtcc.timetablehelper.ApiWebservice;
import de.oszimtcc.timetablehelper.Converter;
import de.oszimtcc.timetablehelper.ObjectSerializator;
import de.oszimtcc.timetablehelper.RequestCache;


/**
 * @author Kooki
 *
 */
public class Timetable implements Iterable<Day>, Serializable
{
	private List<Day> DayList = new ArrayList<Day>();	
	private Date startDate;
	private String className;

	public Timetable(Document pTimetable)
	{
		final String[] requestedDays = TimetableApplication.getInstance().getResources().getStringArray(R.array.Wochentage);
		Document doc = pTimetable;
		String date = ((Element)doc.getFirstChild()).getAttribute("date");
		if(date != null && date.length() > 1)
			this.startDate = new Date(date);
		else
			this.startDate = new Date();
		
		this.className = ((Element)doc.getFirstChild()).getAttribute("class");
		
		for (int i = 0; i < requestedDays.length; i++)
        {
			Calendar cal = Calendar.getInstance();
			cal.add(Calendar.DAY_OF_MONTH, +i);
			DayList.add(DayFactory.DayFromNode(doc.getElementsByTagName(requestedDays[i]).item(0), i,cal.getTime()));
        }
	}
	
	public Timetable(String pTimetable)
	{
		final String[] requestedDays = TimetableApplication.getInstance().getResources().getStringArray(R.array.Wochentage);
		Document doc = Converter.DocumentConverter.DocFromString(pTimetable);
		try
		{
			this.startDate = new Date(((Element)doc.getFirstChild()).getAttribute("date").replace('.', '/'));
		}
		catch(Exception e)
		{
		}
		
		for (int i = 0; i < requestedDays.length; i++)
        {
			Calendar cal = Calendar.getInstance();
			cal.add(Calendar.DAY_OF_MONTH, +i);
			DayList.add(DayFactory.DayFromNode(doc.getElementsByTagName(requestedDays[i]).item(0), i,cal.getTime()));
        }
	}
	
	public List<Day> getDayList()
	{
		return DayList;
	}	
	
	public Date getStartDate()
	{
		return startDate;
	}
	
	public String getClassName()
	{
		return this.className;
	}

	@Override
    public Iterator<Day> iterator()
    {
	    return this.DayList.iterator();
    }
	
	public ContentValues ToContentValue()
	{
		ContentValues toStore = new ContentValues();
		toStore.put("class", this.className);
		toStore.put("timetable", ObjectSerializator.SerializeTimetable(this));
		toStore.put("starttime", this.startDate.getTime());
		return toStore;
	}
	
	public Boolean CompareAndSaveChanges(Timetable pToCompare)
	{
        Boolean smthChanged = false;
        Timetable toCompare = pToCompare;
        for(int day = 0; day < this.getDayList().size(); day++)
        {
        	Day changeDay = toCompare.getDayList().get(day); 
        	Day baseDay = this.getDayList().get(day);
	        for(int block = 0; block < changeDay.BlockList.size(); block++)
            {
	        	Block changeBlock = changeDay.BlockList.get(block);
	        	changeBlock.SetHasNewChanges(true);
	        	if(changeBlock.GetBlockNumber() > baseDay.GetBlockAmount())
	        	{
	        		if(changeBlock.GetBlockNumber() > 0)
	        			this.getDayList().get(day).BlockList.add(changeBlock.GetBlockNumber() - 1, changeBlock);
	        		else
	        			this.getDayList().get(day).BlockList.add(0, changeBlock);
	        	}
	        	else
	        	{
	        		if(changeBlock.GetBlockNumber() > 0)
	        		{
	        			if(this.getDayList().get(day).BlockList.get(0).GetBlockNumber() == 0)
	        				this.getDayList().get(day).BlockList.set(changeBlock.GetBlockNumber(), changeBlock);
	        			else
	        				this.getDayList().get(day).BlockList.set(changeBlock.GetBlockNumber() - 1, changeBlock);
	        		}
	        		else
	        		{
	        			if(this.getDayList().get(day).BlockList.get(0).GetBlockNumber() == 0)
	        				this.getDayList().get(day).BlockList.set(0, changeBlock);
	        			else
	        				this.getDayList().get(day).BlockList.add(0, changeBlock);
	        		}
	        	}
	        	smthChanged = true;
            }
        }
        if(smthChanged)
        {
        	RequestCache.getInstance(this.className).ChangeLastTimetable(this);
        	return smthChanged;
        }
        return false;
	}
	
	@Override
	public String toString()
	{
		return "Timetable for " + this.className;//return String.format("Timetable for %s from %s\n, args)
	}
}
